#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2025 粤港澳大湾区（广东）国创中心

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

File: DialogData.py
Desc: Dialog for inputting various types of data.
Author: xumanjia
Date: 2025-08-01
"""
import os
import sys
from PyQt5.QtCore import QFileInfo
from PyQt5.QtWidgets import QApplication, QDesktopWidget, QFrame, QHBoxLayout, QLabel, QLineEdit, QDialog, QMessageBox, QWidget, QVBoxLayout, QFormLayout, QPushButton, QFileDialog
from PyQt5.QtGui import QFont, QColor, QIcon, QKeySequence
from PyQt5.QtCore import Qt, QTimer, QThread, pyqtSignal, QProcess
# from ncti_python import NCTI  # type: ignore
from Dialog.NctiLineEditBoundData import NctiLineEditBoundData,NctiComboBoxData,NctiPushButtonData  # type: ignore
from Dialog.PythonPreviewDlg import PreviewLabel
from Pub.configLoad import global_scope

class DialogData(QDialog):
    closePreview = pyqtSignal()
    def __init__(self, parent=None):
        super().__init__(parent)
        global  global_scope
        self.doc = global_scope["doc"]
        self.NCTI = global_scope["NCTI"]

    def initWidgets(self, *args):         
        self.argsList = list(args)
        numArgs = len(self.argsList)
        # self.NCTI = self.argsList[numArgs- 1]
        # self.argsList.remove(self.NCTI)  # 移除最后一个参数 NCTI 对象
        self.outList = []
        self.LineEditList = []
        self.ComboBoxList = []
        self.PushButtonList = []
        argsList = self.argsList
        if len(argsList) % 2 != 0:
            raise ValueError("参数个数必须为偶数")
        
        self.setWindowIcon(QIcon('resource/ncti.ico'))
        self.setWindowTitle(argsList[1])
        self.setGeometry(100, 100, 400, 200)
        self.setFont(QFont("Arial", 12))
        # 创建中心部件
        self.central_widget = QFrame(self)
        # self.setCentralWidget(self.central_widget)
        layoutMain = QVBoxLayout(self.central_widget)
        layout = QFormLayout()
        layout.setLabelAlignment(Qt.AlignRight)
        layout.setFormAlignment(Qt.AlignLeft)
        layoutMain.addLayout(layout)

        for i in range(2, len(argsList), 2):
            caption = argsList[i]
            value = argsList[i + 1]
            self.outList.append(value)  # 收集输出值
            lable = QLabel(caption)
            if isinstance(value, str):
                lineEdit = NctiLineEditBoundData(value)
                layout.addRow(lable, lineEdit)
                self.LineEditList.append(lineEdit)
            elif isinstance(value, int):
                lineEdit = NctiLineEditBoundData(value)
                layout.addRow(lable, lineEdit)
                self.LineEditList.append(lineEdit)
            elif isinstance(value, float):
                lineEdit = NctiLineEditBoundData(value)
                layout.addRow(lable, lineEdit)
                self.LineEditList.append(lineEdit)
            elif isinstance(value,list):
                comBox = NctiComboBoxData(value)
                layout.addRow(lable, comBox)
                self.LineEditList.append(comBox)
            elif isinstance(value, dict):
                if "sel" in value:
                    selLabel = QLabel("未选择")
                    button = NctiPushButtonData("选取", value, selLabel)
                    button.clicked.connect(lambda: self.on_selbutton_clicked(button))
                    hlayout = QHBoxLayout()
                    hlayout.addWidget(selLabel)
                    hlayout.addWidget(button)
                    layout.addRow(lable, hlayout)
                    self.PushButtonList.append(button)
                elif "selFile" in value or "selFiles" in value:
                    lineEdit = NctiLineEditBoundData("选择文件")
                    lineEdit.setReadOnly(True)
                    button1 = NctiPushButtonData("选取", value, lineEdit)
                    button1.clicked.connect(lambda: self.on_selFilebutton_clicked(button1))
                    hlayout = QHBoxLayout()
                    hlayout.addWidget(lineEdit)
                    hlayout.addWidget(button1)
                    layout.addRow(lable, hlayout)
                    self.LineEditList.append(lineEdit)
                    self.PushButtonList.append(button1)
                elif "selFolder" in value:
                    lineEdit = NctiLineEditBoundData("选择文件夹")
                    lineEdit.setReadOnly(True)
                    button2 = NctiPushButtonData("选取", value, lineEdit)
                    button2.clicked.connect(lambda: self.on_selFilebutton_clicked(button2))
                    hlayout = QHBoxLayout()
                    hlayout.addWidget(lineEdit)
                    hlayout.addWidget(button2)
                    layout.addRow(lable, hlayout)
                    self.LineEditList.append(lineEdit)
                    self.PushButtonList.append(button2)
                elif "saveFile" in value:
                    lineEdit = NctiLineEditBoundData("保存文件")
                    lineEdit.setReadOnly(True)
                    button3 = NctiPushButtonData("打开目录", value, lineEdit)
                    button3.clicked.connect(lambda: self.on_selFilebutton_clicked(button3))
                    hlayout = QHBoxLayout()
                    hlayout.addWidget(lineEdit)
                    hlayout.addWidget(button3)
                    layout.addRow(lable, hlayout)
                    self.LineEditList.append(lineEdit)
                    self.PushButtonList.append(button3)
            elif type(value).__name__ == "Vector":
                lineEditX = NctiLineEditBoundData(value.X)
                lineEditY = NctiLineEditBoundData(value.Y)
                lineEditZ = NctiLineEditBoundData(value.Z)
                self.LineEditList.append(lineEditX)
                self.LineEditList.append(lineEditY)
                self.LineEditList.append(lineEditZ)
                HLayout = QHBoxLayout()
                HLayout.addWidget(lineEditX)
                HLayout.addWidget(lineEditY)
                HLayout.addWidget(lineEditZ)
                layout.addRow(lable, HLayout)
            elif type(value).__name__ == "Point":
                lineEditX = NctiLineEditBoundData(value.X)
                lineEditY = NctiLineEditBoundData(value.Y)
                lineEditZ = NctiLineEditBoundData(value.Z)
                self.LineEditList.append(lineEditX)
                self.LineEditList.append(lineEditY)
                self.LineEditList.append(lineEditZ)
                HLayout = QHBoxLayout()
                HLayout.addWidget(lineEditX)
                HLayout.addWidget(lineEditY)
                HLayout.addWidget(lineEditZ)
                layout.addRow(lable, HLayout)
                # layout.addRow(lable, f"{value:.2f}")
            # elif isinstance(value, tuple) and len(value) == 3:
            #     layout.addRow(lable, f"({value[0]:.2f}, {value[1]:.2f}, {value[2]:.2f})")
            else:
                lineEdit = NctiLineEditBoundData(str(value))
                layout.addRow(lable, lineEdit)

        ok_button = QPushButton("确定", self)
        cancel_button = QPushButton("退出", self)
        ok_button.clicked.connect(self.on_ok_button_click)
        cancel_button.clicked.connect(self.on_cancel_button_click)
        
        HLayout3 = QHBoxLayout()
        HLayout3.addWidget(cancel_button)
        HLayout3.addWidget(ok_button)
        layoutMain.addLayout(HLayout3)
        self.setLayout(layoutMain)

        
        # 居中显示
        screen = QDesktopWidget().screenGeometry()
        window_size = self.geometry()
        window_center = QDesktopWidget().availableGeometry().center()
        qr = self.frameGeometry()
        qr.moveCenter(window_center)
        self.move(qr.topLeft())

    def on_ok_button_click(self):
        for lineEdit in self.LineEditList:
            lineEdit.accept()
        for comboBox in self.ComboBoxList:
            comboBox.accept()
        pos = -1
        btnPos = -1
        for i in range(0, len(self.outList), 1):
            pos += 1
            if isinstance(self.outList[i], str):
                self.outList[i] = self.LineEditList[pos].value
            elif isinstance(self.outList[i], int):
                self.outList[i] = self.LineEditList[pos].value
            elif isinstance(self.outList[i], float):
                self.outList[i] = self.LineEditList[pos].value
            elif type(self.outList[i]).__name__ == "Vector":
                self.outList[i].X = self.LineEditList[pos].value
                pos += 1
                self.outList[i].Y = self.LineEditList[pos].value
                pos += 1
                self.outList[i].Z = self.LineEditList[pos].value
            elif type(self.outList[i]).__name__ == "Point":
                self.outList[i].X = self.LineEditList[pos].value
                pos += 1
                self.outList[i].Y = self.LineEditList[pos].value
                pos += 1
                self.outList[i].Z = self.LineEditList[pos].value
            elif isinstance(self.outList[i],list):
                text = self.LineEditList[pos].currentText()
                self.outList[i].clear()
                self.outList[i].append(text)
            elif isinstance(self.outList[i],dict):
                btnPos += 1
                self.outList[i] = self.PushButtonList[btnPos].value
          
        self.accept()
        self.closePreview.emit()

    def on_cancel_button_click(self):
        self.reject()
        self.closePreview.emit()  # 发射关闭信号

    def on_selbutton_clicked(self, btn):
        if False == hasattr(self, 'doc'):
            return
        
        selObjNames = {}
        self.doc.ResetCaseResult()
        sel  = self.NCTI.SelectionManager(self.doc)
        if len(sel.ObjectNames) > 0:
            selObjNames["names"] = sel.ObjectNames
            btn.setShowText("已选择")
            btn.setValue(selObjNames)

    def on_selFilebutton_clicked(self, btn):
        if False == hasattr(self, 'doc'):
            return
        
        fileValue = btn.getValue()
        if False == isinstance(fileValue, dict):
            print("Parameter type error. The correct parameter type is a dictionary.")
            return
        
        if "selFile" in fileValue and "filter" in fileValue:
            fileFilter = fileValue["filter"]

            # 打开文件选择对话框
            filePath, selected_filter = QFileDialog.getOpenFileName(
                self,
                "选择单个文件",  # 对话框标题
                os.path.expanduser("~"),
                fileFilter
            )
            if filePath:
                fileValue["selFile"] = filePath
                btn.setValue(fileValue)
                btn.setShowText(filePath)
        elif "selFiles" in fileValue and "filter" in fileValue:
            fileFilter = fileValue["filter"]

            # 打开多文件选择对话框
            filePaths, selected_filter = QFileDialog.getOpenFileNames(
                self,
                "选择多个文件",  # 对话框标题
                os.path.expanduser("~"),
                fileFilter
            )
            if filePaths:
                fileValue["selFiles"] = filePaths
                btn.setValue(fileValue)
                btn.setShowText(", ".join(filePaths))
        elif "selFolder" in fileValue:
            folderPath = QFileDialog.getExistingDirectory(
                self,
                "选择文件夹",  # 对话框标题
                os.path.expanduser("~"),  # 起始目录
                QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks  # 选项
            )
            if folderPath:
                fileValue["selFolder"] = folderPath
                btn.setValue(fileValue)
                btn.setShowText(folderPath)
        elif "saveFile" in fileValue and "filter" in fileValue:
            filePath = fileValue["saveFile"]
            if not filePath:
                print("Invalid input file path")
                return
            
            fileInfo = QFileInfo(filePath)
            fileFilter = fileValue["filter"]
            # 打开文件保存对话框
            filePath, selected_filter = QFileDialog.getSaveFileName(
                self,
                "保存文件",  # 对话框标题
                os.path.expanduser("~") + f"/{fileInfo.fileName()}",  # 默认路径和文件名
                fileFilter  # 文件过滤器
            )
            if filePath:
                fileValue["saveFile"] = filePath
                btn.setValue(fileValue)
                btn.setShowText(filePath)

    def closeEvent(self, event):
        """重写关闭事件，触发自定义信号"""
        self.closePreview.emit()  # 发射关闭信号
        super().closeEvent(event)

def InputDialog(*arg):
    argsList = list(arg)
    if len(argsList) % 2 != 0:
        print(f"输入参数错误: {arg}")
        QMessageBox.critical(None, "错误", f"输入参数错误: {arg}")
        return()
    window = DialogData()
    window.initWidgets(*arg)
    preview = PreviewLabel(window)
    window.installEventFilter(preview)
    preview.show()
    window.show()
    if window.exec_() == QDialog.Accepted:
        val = tuple(window.outList)
        #print(val)
        return val
    return ()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = DialogData()
    window.initWidgets(-1, "六棱柱参数", "内核",["OCC","PS","PK","OD"], "底部中心点坐标", 0.0, "腔体宽度", 30.0, "腔体高度", 50.0, "内嵌颈内径",  4.3, "内嵌颈长度", 30.0, "橡胶层厚度", 10.0, "腔体厚度", 1.0, "内嵌颈厚度", 1.0, "行数", 1.0, "列数", 1.0)
    if window.exec_() == QDialog.Accepted:
        val = tuple(window.outList)
        print(val)
    sys.exit()